简单介绍JNI和NDK
JNI:Java Native Interface,java本地接口,可以使Java与本地其他语言进行交互,如C语言,C++。
NDK:Native Development Kit是Android的一个开发工具包,快速开C与C++的动态库,并自动将so文件和应用一起打包成APK
简单快速方法
先在setting下载好ndk,cmake,lldb,然后新建项目
选择native c++然后next,输入项目名称,一路next到finish。
打开main文件夹下的cpp文件,可以看到已经写好的CMakeLists.txt和native-lib.cpp,native-lib.cpp文件,它是提供对外接口的,之后我们调用时就是通过一个java类调用这个c++文件中的接口的。
打开main文件夹下的build.gradle,填写一些配置
修改成:
build一下就生成了.so文件,在app——>build——>intermediates——>cmake下生成对应的.so库
使用此种方法.so文件声明调用都在MainActivity中,而且对外接口只有一个native-lib.cpp,不能使用多个.cpp文件实现功能。
解决办法:第一种:参考完整版写一个Java文件用javah生成.h文件,完成c代码复制到之前的native-lib.cpp中,然后rebuild;第二种将得到的接口文件(.h文件)在cpp文件夹下新建一个.cpp文件将接口文件的代码复制进去,并在CMakeLists.txt中添加新.cpp文件的源文件地址,rebuild即可。
完整版
个人觉得这个版本复杂很多但是我们可以更完整的了解建立so库的全部过程,对于后面逆向的学习有更好的理解
新建一个空项目,在Project Structure里面配置好NDK,不知道为什么在gradle3.5不能下载应用ndk之后自动配置,每一次要手动配置。
检查是否配置好在gradle这个文件夹下查看local.properties文件里面是否函数有ndk的地址。
新建一个Testjni.java1
2
3
4
5
6
7
8public class MyJni {
static {
System.loadLibrary("testjni");
}
public native static String getString();
}
点击build–>make project,生成.class文件
找到classes文件夹,一般在E:\Android\TestJNI\app\build\intermediates\javac\debug下,使用javah来生成.h文件,命令为1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
在src/main/下创建jni目录将上述.h文件复制进去,并创建.c文件,并把下面代码复制进去
```JAVA
#include <jni.h>
#include "com_example_testjni_testjni.h"
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT jstring JNICALL com_example_testjni_testjni_getString
(JNIEnv *env, jclass jz){
return (*env)->NewStringUTF(env,"this is the first time for me to use jni");
}
#ifdef __cplusplus
}
#endif
再创建Android.mk和Application.mk文件(个人觉得这种太麻烦了,Cmake简单明了)
Android.mk是一个向Android NDK构建系统描述NDK项目的GNU makefile片段。我的理解是链接文件,告诉ndk操作的一些信息
Android.mk1
2
3
4
5
6
7
8
9
10#定义模块当前路径(必须定义在文件开头,只需定义一次)
LOCAL_ PATH := $(call my-dir)
#清空当前环境变量 (LOCAL_PATH除外)
include $(CLEAR_VARS )
#当前模块名(这里会生成libhello-jni.so),模块名唯一,且不能包含空格
LOCAL_MODULE := testjni
#当前模块包含的源代码文件
LOCAL_ SRC_ FILES := test.c
#表示当前模块将被编译成一个共享库
include $(BUILD_ SHARED_LIBRARY)
Application.mk1
APP_ABI := armeabi armeabi-v7a x86 // 生成so文件的平台 ,设置为all, 代表所有平台
切换到main目录下 执行ndk-build 生成so文件
将我们生成的so文件复制到 app下的libs文件夹下,并配置build.gradle 文件
在MainActivity中调用
别问我图在哪儿,上传不了。